<template>
	<scroll-view scroll-y 
	@scrolltolower="onScrollToBottom"
	:style="{height:props.height+'rpx'}"
	>
		<refresh  @refresh="onrefresh" @pullingdown="onpullingdown" :display="showLoading ? 'show' : 'hide'">
		    <slot name="pull" :status="{refreshStatus}">
		    	<view class="flex flex-row flex-row-center-center" :style="{height:(_barHeight/2)+'px',opacity:refreshStatus ==2||refreshStatus ==3?1:0}">
		    		<tm-icon :font-size="24" color="primary" name="tmicon-shuaxin" spin></tm-icon>
		    		<tm-text color="grey" _class="pl-16" :label="loadingTexts[refreshStatus]"></tm-text>
		    	</view>
		    	<view v-if="refreshStatus != -1 && refreshStatus != 2"
		    		class="flex flex-row flex-row-center-center srrryration"
		    		:style="{opacity:`${refreshStatus==0?(_barHeight/nowEvt.viewHeight):1}`,height:(_barHeight/2)+'px'}">
		    		<view :class="refreshStatus==0?'srrryration srrryrationOn':'srrryration srrryrationOf'">
		    			<tm-icon :font-size="24" color="primary" name="tmicon-long-arrow-down"></tm-icon>
		    		</view>
		    		<tm-text color="grey" _class="pl-16" :label="loadingTexts[refreshStatus]"></tm-text>
		    	</view>
		    </slot>
		</refresh>
		<slot></slot>
	</scroll-view>
</template>

<script lang="ts" setup >
	import tmIcon from "../tm-icon/tm-icon.vue"
	import tmText from "../tm-text/tm-text.vue"
	import {
		getCurrentInstance,
		nextTick,
		onMounted,
		ref,
		Ref,
		watch
	} from 'vue';
	import { propsdetail } from "./propsdetail"
	const proxy = getCurrentInstance()?.proxy ?? null
	const emits = defineEmits(["bottom", "change", "refresh", "timeout", "update:modelValue", "update:bottomValue"])
	const props = defineProps({
		...propsdetail
	})
	interface pullevent {
		dy:number,
		pullingDistance:number,
		viewHeight:number,
		type:string
	}
	const showLoading = ref(false)
	const refreshing = ref(false)
	const isBootRefresh = ref(false)
	const refreshStatus = ref(-1)
	/** 开始刷新 - 刷新成功/失败 最大间隔时间setTimeout句柄 */
	let maxRefreshAnimateTimeFlag: number | null = 0;
	const _barHeight = ref(uni.$tm.u.topx(props.loadBarHeight))
	const nowEvt:Ref<pullevent> = ref({
		dy:0,
		pullingDistance:0,
		viewHeight:0,
		type:''
	})
	
	onMounted(()=>{
		if(maxRefreshAnimateTimeFlag!=null){
			clearTimeout(maxRefreshAnimateTimeFlag)
		}
	})
	watch(() => props.modelValue, () => {
		if (!props.modelValue) {
			if (maxRefreshAnimateTimeFlag != null) {
				clearTimeout(maxRefreshAnimateTimeFlag);
			}
			close();
		}
	})
	watch(() => props.bottomValue, () => {
		isBootRefresh.value = props.bottomValue;
	})
	function onScrollToBottom() {
		if (isBootRefresh.value) return;
		emits("update:bottomValue",true)
		isBootRefresh.value = true;
		emits("bottom")
	}
	function onrefresh(){
		if(nowEvt.value.pullingDistance>=_barHeight.value){
			refreshStatus.value = 2;
			showLoading.value = true;
			emits("refresh")
			emits("change",true)
			emits("update:modelValue", true);
			maxRefreshAnimateTimeFlag = setTimeout(() => {
				maxRefreshAnimateTimeFlag = null;
				if (refreshStatus.value === 2) {
					// 超时回调
					emits("timeout")
					close(); // 超时仍未被回调，则直接结束下拉
				}
			}, props.refreshTimeout as any) as any as number;
			
			return;
		}
		if(refreshStatus.value==-1||refreshStatus.value==0){
			showLoading.value = true;
			nextTick(()=>{
				showLoading.value = false
				emits("change",false)
			})
		}
		
		
	}
	/**
	 * dy: 前后两次回调滑动距离的差值
	pullingDistance: 下拉的距离
	viewHeight: refresh 组件高度
	type: “pullingdown” 常数字符串
	 */
	function onpullingdown(evt:{dy:number,pullingDistance:number,viewHeight:number,type:string}){
		nowEvt.value = evt;
		
		if(evt.pullingDistance<=1){
			refreshStatus.value = -1;
		}else if(evt.pullingDistance>1&&evt.pullingDistance<_barHeight.value){
			refreshStatus.value = 0;
		}else if(evt.pullingDistance>=_barHeight.value){
			refreshStatus.value = 1;
		}
	}
	

	function close() {
		showLoading.value = false
		refreshStatus.value = 3;
		emits('change', false)
		emits("update:modelValue", false);
	}
	
</script>

<style>
	.srrryration {
		transition-property: transform,height,opacity;
		transition-timing-function: ease;
		transition-duration: 0.25s;
	}

	.srrryrationOn {
		transform: rotate(0deg);
	}

	.srrryrationOf {
		transform: rotate(180deg);
	}
</style>
